#include<iostream>
#include<vector>

#include<thread>
#include<mutex>
#include<condition_variable>
#include<atomic>

#include<fstream>
#include<sstream>


using namespace std;

//int main()
//{
//	int n,m;
//	cin>>n>>m;
//
//	vector<thread> v;
//	v.resize(n);
//
//	for (auto& t : v)
//	{
//		t = thread([m] {
//				for (size_t i = 0; i < m; ++i)
//				{
//					cout << this_thread::get_id() << ":" << i << endl;
//				}
//			});
//	}
//
//	for (auto& t : v)
//	{
//		t.join();
//	}
//
//	return 0;
//}

//int val = 0;
//mutex mtx;
//atomic<int> aval = 0;
//
//void Func1(int n)
//{
//	/*for (size_t i = 0; i < n; i++)
//	{
//		mtx.lock();
//
//		++val;
//
//		mtx.unlock();
//	}*/
//
//	/*mtx.lock();
//	for (size_t i = 0; i < n; i++)
//	{
//		++val;
//	}
//	mtx.unlock();*/
//
//	for (size_t i = 0; i < n; i++)
//	{
//		++aval;
//	}
//}
////
////void Func2(int n)
////{
////	for (size_t i = 0; i < n; i++)
////	{
////		mtx.lock();
////		++val;
////		mtx.unlock();
////	}
////}
//
//// 10:32继续
//int main()
//{
//	int m = 10000000;
//	thread t1(Func1, 2*m);
//	thread t2(Func1, m);
//
//	t1.join();
//	t2.join();
//
//	cout << aval << endl;
//
//	return 0;
//}

//////////////////////////////////////////////////////////////////////////////////////////

//int main()
//{
//	int m = 10000000;
//	atomic<int> aval = 0;
//
//	auto func = [&aval](int n){
//		for (size_t i = 0; i < n; i++)
//		{
//			++aval;
//			this_thread::sleep_for(std::chrono::milliseconds(2000));
//			cout << aval << endl;
//		}
//	};
//
//	thread t1(func, m*2);
//	thread t2(func, m);
//
//	t1.join();
//	t2.join();
//
//	cout << aval << endl;
//
//	return 0;
//}


//int main()
//{
//	int m = 10000000;
//	atomic<int> aval = 0;
//	mutex mtx;
//
//	//auto func = [&aval, &mtx](int n) {
//	//	for (size_t i = 0; i < n; i++)
//	//	{
//	//		++aval;
//
//	//		//mtx.lock();
//	//		lock_guard<mutex> lock(mtx);
//	//		cout <<this_thread::get_id()<<"->"<< aval << endl;
//	//		//mtx.unlock();
//	//	}
//	//};
//
//	// 休息11:44继续
//	auto func = [&aval, &mtx](int n) {
//		for (size_t i = 0; i < n; i++)
//		{
//			{
//				lock_guard<mutex> lock(mtx);  // RAII
//				cout << this_thread::get_id() << "->" << aval << endl;
//			}
//
//			++aval;
//		}
//	};
//
//	thread t1(func, m * 2);
//	thread t2(func, m);
//
//	t1.join();
//	t2.join();
//
//	cout << aval << endl;
//
//	return 0;
//}


// 支持两个线程交替打印，t1一个打印奇数，t2一个打印偶数,打印到100
//int main()
//{
//	int i = 0;
//	thread t1([&i] {
//		while (i < 100)
//		{
//			if (i % 2)
//			{
//				cout << this_thread::get_id() << "->" << i << endl;
//				++i;
//			}
//		}
//		});
//
//	thread t2([&i] {
//		while (i <= 100)
//		{
//			if (i % 2 == 0)
//			{
//				cout << this_thread::get_id() << "->" << i << endl;
//				++i;
//			}
//		}
//		});
//
//	t1.join();
//	t2.join();
//
//	return 0;
//}
//int main()
//{
//	int i = 0;
//	thread t1([&i] {
//		while (i < 100000)
//		{
//			if (i % 2)
//			{
//				cout << this_thread::get_id() << "->" << i << endl;
//				++i;
//
//				//this_thread::sleep_for(std::chrono::microseconds(500));
//			}
//		}
//		});
//
//	thread t2([&i] {
//		while (i <= 100000)
//		{
//			if (i % 2 == 0)
//			{
//				cout << this_thread::get_id() << "->" << i << endl;
//				++i;
//				//this_thread::sleep_for(std::chrono::microseconds(500));
//			}
//		}
//		});
//
//	t1.join();
//	t2.join();
//
//	return 0;
//}


//int main()
//{
//	int i = 0;
//	mutex mtx;
//	thread t1([&i, &mtx] {
//		while (i < 100)
//		{
//			mtx.lock();
//			cout << this_thread::get_id() << "->" << i << endl;
//			++i;
//			mtx.unlock();
//		}
//		});
//
//	thread t2([&i, &mtx] {
//		while (i <= 100)
//		{
//			mtx.lock();
//			cout << this_thread::get_id() << "->" << i << endl;
//			++i;
//			mtx.unlock();
//		}
//		});
//
//	t1.join();
//	t2.join();
//
//	return 0;
//}

// 支持两个线程交替打印，t1一个打印奇数，t2一个打印偶数,打印到100

//int main()
//{
//	int i = 0;
//	mutex mtx;
//	condition_variable cv;
//	bool flag = true;
//
//	// 奇数 -- flag = false
//	thread t1([&] {
//		while (i < 100)
//		{
//			unique_lock<mutex> lock(mtx);
//			while (flag == true)
//				cv.wait(lock);  // 阻塞
//
//			cout <<"t1:" << this_thread::get_id() << "->" << i << endl;
//			++i;
//
//			flag = true;
//
//			cv.notify_one();
//		}
//		});
//
//	// 偶数  -- flag = true
//	thread t2([&] {
//		while (i <= 100)
//		{
//			unique_lock<mutex> lock(mtx);
//			while(flag == false)
//				cv.wait(lock);  // 阻塞
//
//			cout <<"t2:"<< this_thread::get_id() << "->" << i << endl;
//			++i;
//			flag = false;
//
//			cv.notify_one();
//		}
//		});
//
//	t1.join();
//	t2.join();
//
//	return 0;
//}

//int main()
//{
//	int i = 0;
//	mutex mtx;
//	condition_variable cv;
//	bool flag = true;
//	int n = 1000000;
//
//	// 奇数 -- flag = false
//	thread t1([&] {
//		while (i < n)
//		{
//			unique_lock<mutex> lock(mtx);
//			//while (i % 2 == 0)  // 偶数
//			//	cv.wait(lock);  // 阻塞
//			cv.wait(lock, [&i] {return i % 2; });
//
//			cout << "t1:" << this_thread::get_id() << "->" << i << endl;
//			++i;
//
//			cv.notify_one();
//		}
//		});
//
//	// 偶数  -- flag = true
//	thread t2([&] {
//		while (i <= n)
//		{
//			unique_lock<mutex> lock(mtx);
//			//while (i % 2)       // 奇数
//			//	cv.wait(lock);  // 阻塞
//			cv.wait(lock, [&i] {return i % 2 == 0; });
//
//			cout << "t2:" << this_thread::get_id() << "->" << i << endl;
//			++i;
//
//			cv.notify_one();
//		}
//		});
//
//	t1.join();
//	t2.join();
//
//	return 0;
//}

///////////////////////////////////////////////////////////////
//int main()
//{
//	cout << "111111111" << endl;
//	//cerr << "111111111" << endl;
//
//	return 0;
//}

//class A
//{
//public:
//	A(int a)
//		:_a1(1)
//		,_a2(2)
//	{}
//
//	operator int()
//	{
//		return _a1 + _a2;
//	}
//
//private:
//	int _a1;
//	int _a2;
//};
//
//int main()
//{
//	string str;
//	while (cin >> str)
//	{
//		cout << str << endl;
//	}
//
//	// 内置类型隐式类型转换成自定义类型
//	A aa1 = 1;
//
//	// 自定义类型隐式类型转换成内置类型
//	int a = aa1;
//
//	cout << a << endl;
//}

class Date
{
	friend ostream& operator << (ostream& out, const Date& d);
	friend istream& operator >> (istream& in, Date& d);
public:
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}

	operator bool()
	{
		// 这里是随意写的，假设输入_year为0，则结束
		if (_year == 0)
			return false;
		else
			return true;
	}
private:
	int _year;
	int _month;
	int _day;
};

istream& operator >> (istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}

ostream& operator << (ostream& out, const Date& d)
{
	out << d._year << " " << d._month << " " << d._day;
	return out;
}

// C++ IO流，使用面向对象+运算符重载的方式
// 能更好的兼容自定义类型，流插入和流提取
//int main()
//{
//	// 自动识别类型的本质--函数重载
//	// 内置类型可以直接使用--因为库里面ostream类型已经实现了
//	int i = 1;
//	double j = 2.2;
//	cout << i << endl;
//	cout << j << endl;
//
//	// 自定义类型则需要我们自己重载<< 和 >>
//	Date d(2022, 4, 10);
//	cout << d;
//	while (d)
//	{
//		cin >> d;
//		cout << d;
//	}
//
//	return 0;
//}

// 二进制读写
//struct ServerInfo
//{
//	char _address[32];
//	//string _address;
//	int _port;
//
//	//Date _date;
//};
//
//struct ConfigManager
//{
//public:
//	ConfigManager(const char* filename)
//		:_filename(filename)
//	{}
//
//	void WriteBin(const ServerInfo& info)
//	{
//		//ofstream ofs(_filename, ofstream::out | ofstream::binary);
//		ofstream ofs(_filename, ios_base::out | ios_base::binary);
//		ofs.write((char*)&info, sizeof(info));
//	}
//
//	void ReadBin(ServerInfo& info)
//	{
//		ifstream ifs(_filename, ios_base::in | ios_base::binary);
//		ifs.read((char*)&info, sizeof(info));
//	}
//
//private:
//	string _filename; // 配置文件
//};
//
//int main()
//{
//	ConfigManager cm("test.txt");
//	ServerInfo winfo = { "192.0.0.111111111111111111", 80};
//	cm.WriteBin(winfo);
//
//	ServerInfo rinfo;
//	cm.ReadBin(rinfo);
//
//	cout << rinfo._address << endl;
//	cout << rinfo._port << endl;
//
//	return 0;
//}

///////////////////////////////////////////////////////////////////////////
// 文本读写
struct ServerInfo
{
	//char _address[32];

	string _address;
	int _port;
	Date _date;
};

struct ConfigManager
{
public:
	ConfigManager(const char* filename)
		:_filename(filename)
	{}

	void WriteBin(const ServerInfo& info)
	{
		//ofstream ofs(_filename, ofstream::out | ofstream::binary);
		ofstream ofs(_filename, ios_base::out | ios_base::binary);
		ofs.write((char*)&info, sizeof(info));
	}

	void ReadBin(ServerInfo& info)
	{
		ifstream ifs(_filename, ios_base::in | ios_base::binary);
		ifs.read((char*)&info, sizeof(info));
	}

	void WriteText(const ServerInfo& info)
	{
		ofstream ofs(_filename);
		ofs << info._address << endl;
		ofs << info._port << endl;
		ofs << info._date << endl;
	}

	void ReadText(ServerInfo& info)
	{
		ifstream ifs(_filename);
		ifs >> info._address;
		ifs >> info._port;
		ifs >> info._date;
	}

private:
	string _filename; // 配置文件
};

//int main()
//{
//	ConfigManager cm("test.txt");
//	ServerInfo winfo = { "192.0.0.111111111111111111", 80, {2023,4,1} };
//	cm.WriteText(winfo);
//
//	ServerInfo rinfo;
//	cm.ReadText(rinfo);
//	cout << rinfo._address << endl;
//	cout << rinfo._port << endl;
//	cout << rinfo._date << endl;
//
//	return 0;
//}
//
//int main()
//{
//	int i = 1234;
//	double dl = 2.22;
//	Date d = { 2023, 4, 1 };
//	ostringstream oss;
//	oss << i << " ";
//	oss << dl << " ";
//	oss << d << " ";
//	string str = oss.str();
//	cout << str << endl;
//
//	int j;
//	double dll;
//	Date dd;
//	istringstream iss(str);
//	iss >> j >> dll >> dd;
//
//	return 0;
//}

// 序列化和反序列化
struct ChatInfo
{
	string _name; // 名字
	int _id;      // id
	Date _date;   // 时间
	string _msg;  // 聊天信息
};

int main()
{
	// 序列化
	ChatInfo winfo = { "张三", 135246, { 2023, 4, 1 }, "晚上一起看电影吧" };
	stringstream oss;
	oss << winfo._name << endl;
	oss << winfo._id << endl;
	oss << winfo._date<< endl;
	oss << winfo._msg << endl;
	string str = oss.str();
	cout <<"网络发送：" << str << endl;

	// 反序列化
	ChatInfo rInfo;
	stringstream iss(str);
	iss >> rInfo._name >> rInfo._id >> rInfo._date >> rInfo._msg;
	cout << "-------------------------------------------------------" << endl;
	cout << "姓名：" << rInfo._name << "(" << rInfo._id << ") ";
	cout << rInfo._date << endl;
	cout << rInfo._name << ":>" << rInfo._msg << endl;
	cout << "-------------------------------------------------------" << endl;

	return 0;
}